"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAxiosConfig = exports.shouldUseProxy = exports.hostnameMatchesNoProxyPattern = exports.getDefaultUserAgentHeader = exports.USER_AGENTS = void 0;
const package_json_1 = require("../package.json");
const config_1 = require("../config");
const urls_1 = require("../lib/urls");
const http_1 = __importDefault(require("http"));
const https_1 = __importDefault(require("https"));
const http_proxy_agent_1 = require("http-proxy-agent");
const https_proxy_agent_1 = require("https-proxy-agent");
// Total number of sockets across all hosts
const MAX_TOTAL_SOCKETS = 25;
// Total number of sockets per each host
const MAX_SOCKETS_PER_HOST = 5;
const httpAgent = new http_1.default.Agent({
    keepAlive: true,
    maxTotalSockets: MAX_TOTAL_SOCKETS,
    maxSockets: MAX_SOCKETS_PER_HOST,
});
const httpsAgent = new https_1.default.Agent({
    keepAlive: true,
    maxTotalSockets: MAX_TOTAL_SOCKETS,
    maxSockets: MAX_SOCKETS_PER_HOST,
});
function getHttpProxyEnvVariable() {
    return process.env.HTTP_PROXY || process.env.http_proxy;
}
function getHttpsProxyEnvVariable() {
    return process.env.HTTPS_PROXY || process.env.https_proxy;
}
function getAllProxyEnvVariable() {
    return process.env.ALL_PROXY || process.env.all_proxy;
}
function getHttpProxyAgent() {
    const proxyUrl = getHttpProxyEnvVariable() || getAllProxyEnvVariable();
    if (!proxyUrl) {
        return httpAgent;
    }
    return new http_proxy_agent_1.HttpProxyAgent(proxyUrl, {
        keepAlive: true,
        maxTotalSockets: MAX_TOTAL_SOCKETS,
        maxSockets: MAX_SOCKETS_PER_HOST,
    });
}
function getHttpsProxyAgent() {
    const proxyUrl = getHttpProxyEnvVariable() ||
        getHttpsProxyEnvVariable() ||
        getAllProxyEnvVariable();
    if (!proxyUrl) {
        return httpsAgent;
    }
    return new https_proxy_agent_1.HttpsProxyAgent(proxyUrl, {
        keepAlive: true,
        maxTotalSockets: MAX_TOTAL_SOCKETS,
        maxSockets: MAX_SOCKETS_PER_HOST,
    });
}
exports.USER_AGENTS = {
    'HubSpot Local Dev Lib': package_json_1.version,
};
function getDefaultUserAgentHeader() {
    let userAgentString = '';
    Object.keys(exports.USER_AGENTS).forEach((userAgentKey, i) => {
        userAgentString += `${i > 0 ? ', ' : ''}${userAgentKey}/${exports.USER_AGENTS[userAgentKey]}`;
    });
    return {
        'User-Agent': userAgentString,
    };
}
exports.getDefaultUserAgentHeader = getDefaultUserAgentHeader;
const DEFAULT_TRANSITIONAL = {
    clarifyTimeoutError: true,
};
function hostnameMatchesNoProxyPattern(hostname, pattern) {
    const hostnameNormalized = hostname.toLowerCase();
    const patternNormalized = pattern.trim().toLowerCase();
    if (patternNormalized === '*') {
        return true;
    }
    if (patternNormalized.startsWith('.')) {
        return hostnameNormalized.endsWith(patternNormalized);
    }
    return (hostnameNormalized === patternNormalized || // exact match (e.g. "api.hubapi.com" matches "api.hubapi.com")
        hostnameNormalized.endsWith(`.${patternNormalized}`) // domain suffix match (e.g. "api.hubapi.com" matches ".hubapi.com")
    );
}
exports.hostnameMatchesNoProxyPattern = hostnameMatchesNoProxyPattern;
function shouldUseProxy(baseURL) {
    if (!getHttpProxyEnvVariable() &&
        !getHttpsProxyEnvVariable() &&
        !getAllProxyEnvVariable()) {
        return false;
    }
    const noProxy = process.env.NO_PROXY || process.env.no_proxy;
    if (noProxy) {
        const hostname = new URL(baseURL).hostname;
        const noProxyList = noProxy.split(',').filter(Boolean);
        if (noProxyList.some(pattern => hostnameMatchesNoProxyPattern(hostname, pattern))) {
            return false;
        }
    }
    return true;
}
exports.shouldUseProxy = shouldUseProxy;
function getAxiosConfig(options) {
    const { env, localHostOverride, headers, ...rest } = options;
    let config;
    try {
        config = (0, config_1.getConfig)();
    }
    catch (e) {
        config = null;
    }
    let httpTimeout = 15000;
    let httpUseLocalhost = false;
    if (config && config.httpTimeout) {
        httpTimeout = config.httpTimeout;
    }
    if (config && config.httpUseLocalhost) {
        httpUseLocalhost = config.httpUseLocalhost;
    }
    const baseURL = (0, urls_1.getHubSpotApiOrigin)(env, localHostOverride ? false : httpUseLocalhost);
    return {
        baseURL,
        headers: {
            ...getDefaultUserAgentHeader(),
            ...(headers || {}),
        },
        timeout: httpTimeout,
        transitional: DEFAULT_TRANSITIONAL,
        // Disable axios's built-in proxy handling - we use custom agents instead
        proxy: false,
        httpAgent: shouldUseProxy(baseURL) ? getHttpProxyAgent() : httpAgent,
        httpsAgent: shouldUseProxy(baseURL) ? getHttpsProxyAgent() : httpsAgent,
        ...rest,
    };
}
exports.getAxiosConfig = getAxiosConfig;
